package im.composer.midi;

import java.util.Map.Entry;
import java.util.NavigableMap;
import java.util.TreeMap;

public class MidiFreq {

	private static NavigableMap<Integer, Double> key2freq = new TreeMap<>();
	private static NavigableMap<Double, Integer> freq2key = new TreeMap<>();
	static {
		for (int i = 0; i < 128; i++) {
			double f = calcStandard(i);
			key2freq.put(i, f);
			freq2key.put(f, i);
		}
	}

	private MidiFreq() {
	}

	/**
	 * 
	 * @param key
	 *            [0,127]
	 * @param wheel
	 *            [-1,+1] 单位：半音
	 * @return
	 */
	public static final double key2freq(int key, double wheel) {
		if (wheel == 0) {
			return key2freq.get(key);
		}
		return calcStandard(key + wheel);
	}

	private static final double calcStandard(double key) {
		key -= 69;// A4 = 440hz
		double octave = key / 12.0;
		return 440 * Math.pow(2, octave);
	}

	public static Entry<Double, Integer> floorEntry(double freq) {
		return freq2key.floorEntry(freq);
	}
	public static Entry<Double, Integer> ceilEntry(double freq) {
		return freq2key.ceilingEntry(freq);
	}
	public static final double getMaxFreq(){
		return key2freq.lastEntry().getValue();
	}
	public static final double getMinFreq(){
		return key2freq.firstEntry().getValue();
	}
	public static final double getWheeledMaxFreq(){
		return key2freq(127,50);
	}
	public static final double getWheeledMinFreq(){
		return key2freq(0,-50);
	}
}
